"use strict";

var model = module.exports;

var UUID = require("uuid");

// In-memory datastores:
var oauthAccessTokens = {},
    oauthRefreshTokens = {
        "de429ea1e9b442233a3b3ad001707d3572ba6079": {
            "refreshToken": "de429ea1e9b442233a3b3ad001707d3572ba6079",
            "clientId": "plane",
            "user": {"id": "5db12968-94d0-4de3-9fe4-d148df846a9c"},
            "expires": "2018-01-24T10:08:30.824Z"
        }
    },

    oauthAuthCodeTable = {
        "acd8df5fbb2d856fb6dc0896171a52aa24eca299": {
            "authCode": "acd8df5fbb2d856fb6dc0896171a52aa24eca299",
            "clientId": "plane",
            "user": {"id": "00e72d5e-0ff0-4b41-adde-e66cc6a05e7e"},
            "expires": "2017-01-31T14:15:05.000Z"
        }
    },

    // 后台申请权限
    oauthClients = [
        // {clientId : "plane", clientSecret : "THISisAUTO-generatedSECRET", redirectUri : "/oauth/token/test_pass"},
        // {clientId: "plane", clientSecret: "THISisAUTO-generatedSECRET", redirectUri: "/oauth/token/test_auth"},
        // {clientId : "plane", clientSecret : "THISisAUTO-generatedSECRET", redirectUri : "/oauth/token/test_token"},
        //{clientId: "plane", clientSecret: "THISisAUTO-generatedSECRET", redirectUri: "/getSecret"},
        {clientId: "plane", clientSecret: "THISisAUTO-generatedSECRET", redirectUri: "http://localhost:3001/service"},
        {clientId: "airwar", clientSecret: "THISisAUTO-generatedSECRET", redirectUri: "/secret"}
    ],

    // 申请完权限后, 添加授权方式
    authorizedClientIds = {"password": ["plane"], "refresh_token": ["plane"], "authorization_code": ["plane"], "client_credentials": []},

    // 用户在网页进行注册, 创建账号
    users = [{id: "4a5604f624c13712ddf51407b384035458634795", username: "justin", password: "123456"}];

// Debug function to dump the state of the data stores
model.dump = function () {
    console.log("\n\n==========================");
    console.log("Time: [ %j ]", new Date());
    console.log("oauthAccessTokens [ %j ]", oauthAccessTokens);
    console.log("oauthRefreshTokens [ %j ]", oauthRefreshTokens);
    console.log("oauthAuthCodeTable [ %j ]", oauthAuthCodeTable);
    console.log("==========================");
    console.log("authorizedClientIds [ %j ]", authorizedClientIds);
    console.log("oauthClients [ %j ]", oauthClients);
    console.log("users [ %j ]", users);
    console.log("==========================\n\n");
};



/**
 * Required
 */

model.getAccessToken = function (bearerToken, callback) {
    console.log("Get Access Token [ %s ] [ %j ]", bearerToken, oauthAccessTokens);

    // for (var i = 0, len = oauthAccessTokens.length; i < len; i++) {
    //     var elem = oauthAccessTokens[i];
    //     if (elem.accessToken === bearerToken) {
    //         return callback(false, elem);
    //     }
    // }
    // callback(false, false);

    if (oauthAccessTokens[bearerToken]) callback(false, oauthAccessTokens[bearerToken]);
    else callback(false, false);
};

model.saveAccessToken = function (accessToken, clientId, expires, user, callback) {
    console.log("Save Access Token ", accessToken, clientId, expires, user);

    // oauthAccessTokens.unshift({accessToken: accessToken, clientId: clientId, user: user, expires: expires});
    oauthAccessTokens[accessToken] = {accessToken: accessToken, clientId: clientId, user: user, expires: expires};

    callback(false);
};

model.getClient = function (clientId, clientSecret, callback) {
    console.log("Get Client [ %s ] [ %s ] [ %j ]", clientId, clientSecret, oauthClients);
    for (var i = 0, len = oauthClients.length; i < len; i++) {
        var elem = oauthClients[i];
        if (elem.clientId === clientId &&
            (clientSecret === null || elem.clientSecret === clientSecret)) {
            return callback(false, elem);
        }
    }
    callback(false, false);
    // if (oauthClients[clientId] && (clientSecret === null || elem.clientSecret === clientSecret)) callback(false, oauthClients[clientId]);
    // else callback(false, false);
};

// 为后台所用
model.createClient = function (clientId, clientSecret, redirectUri, callback) {
    console.log("Create Client [ %s ] [ %s ] [ %j ]", clientId, clientSecret, redirectUri, oauthClients);
    for (var i = 0, len = oauthClients.length; i < len; i++) {
        var elem = oauthClients[i];
        if (elem.clientId === clientId) {
            return callback(new Error("Client Exists!"));
        }
    }

    var clientinfo = {clientId: clientId, clientSecret: clientSecret, redirectUri: redirectUri};
    oauthClients.push(clientinfo);
    callback(false, clientinfo);
};

model.grantTypeAllowed = function (clientId, grantType, callback) {
    console.log("Get Allowed Type [ %s ] [ %s ] [ %j ]", clientId, grantType, authorizedClientIds);
    callback(false, authorizedClientIds[grantType] &&
        authorizedClientIds[grantType].indexOf(clientId.toLowerCase()) >= 0);
};

// 为后台所用
model.setAllowedGrantType = function (clientId, grantType, open, callback) {
    if (!authorizedClientIds[grantType]) return callback(new Error("Invalid GrandType!"));

    var id = authorizedClientIds[grantType].indexOf(clientId.toLowerCase());
    if (open) {
        // 开启指定模式
        if (id < 0) authorizedClientIds[grantType].push(clientId);
    } else {
        // 关闭指定模式
        if (id > 0) authorizedClientIds[grantType].splice(id);
    }
};



/**
 * Required to support refresh_token grant type
 */

model.getRefreshToken = function (bearerToken, callback) {
    console.log("Get Refresh Token [ %s ] [ %j ]", bearerToken, oauthRefreshTokens);
    // for (var i = 0, len = oauthRefreshTokens.length; i < len; i++) {
    //     var elem = oauthRefreshTokens[i];
    //     if (elem.refreshToken === bearerToken) {
    //         return callback(false, elem);
    //     }
    // }
    // callback(false, false);
    if (oauthRefreshTokens[bearerToken]) callback(false, oauthRefreshTokens[bearerToken]);
    else callback(false, false);
};

model.saveRefreshToken = function (refreshToken, clientId, expires, user, callback) {
    console.log("Save Refresh Token ", refreshToken, clientId, expires, user);

    // oauthRefreshTokens.unshift({refreshToken: refreshToken, clientId: clientId, user: user, expires: expires});
    oauthRefreshTokens[refreshToken] = {refreshToken: refreshToken, clientId: clientId, user: user, expires: expires};

    callback(false);
};



/**
 * Required to support password grant type
 */

model.getUser = function (username, password, callback) {
    console.log("Get User [ %s ] [ %s ] [ %j ]", username, password, users);
    for (var i = 0, len = users.length; i < len; i++) {
        var elem = users[i];
        if (elem.username === username && elem.password === password) {
            return callback(false, elem);
        }
    }
    callback(false, false);
};

// 为后台所用
model.createUser = function (username, password, callback) {
    console.log("Create User [ %s ] [ %s ] [ %j ]", username, password, users);
    for (var i = 0, len = users.length; i < len; i++) {
        var elem = users[i];
        if (elem.username === username) {
            return callback(new Error("User Exists!"));
        }
    }

    var userinfo = {"id":UUID.v4(), "username": username, "password": password};
    users.push(userinfo);
    callback(false, userinfo);
};



/**
 * required for authorization_token grant type
 */

model.getAuthCode = function (bearerCode, callback) {
    console.log("In getAuthCode (bearerCode: " + bearerCode + ")");

    let data = oauthAuthCodeTable[bearerCode];
    if (data && data.expires) {
        data.expires = new Date((data.expires * 1e3));
    }
    callback(data ? null : new Error("No Valid AuthCode!"), data);
};

model.saveAuthCode = function (authCode, clientId, expires, user, callback) {
    console.log("In saveAuthCode authCode: [ %s ] clientId [ %s ] user [ %j ] expires: ", authCode, clientId, user, expires);

    var code = {authCode: authCode, clientId: clientId, user: user};

    if (expires) code.expires = parseInt(expires / 1000, 10);
    console.log("Saving Code Is [ %j ]", code);

    oauthAuthCodeTable[authCode] = code;
    callback(null, code);
};

